package tuanda.soict.firstsun.AbilityPackage;

import java.util.ArrayList;

import tuanda.soict.firstsun.BuildingPackage.Army_Building;
import tuanda.soict.firstsun.BuildingPackage.Building;
import tuanda.soict.firstsun.BuildingPackage.Gold_Building;
import tuanda.soict.firstsun.BuildingPackage.HP_Building;
import tuanda.soict.firstsun.BuildingPackage.HQ_Building;
import tuanda.soict.firstsun.DataPackage.CommonConstants;
import tuanda.soict.firstsun.LogicPackage.Army;
import tuanda.soict.firstsun.LogicPackage.BattleMap;
import tuanda.soict.firstsun.LogicPackage.Coordinate;
import tuanda.soict.firstsun.LogicPackage.Group;
import tuanda.soict.firstsun.LogicPackage.Scenario;

/**
 * @author tuanda_soict_hut
 * @version 0.0.2
 * @since 22-9-2012
 */
public class Occupy extends Ability implements CommonConstants {

	public Occupy(int id, String name, int range, int area, int affect) {
		super(id, name, range, area, affect);
	}

	@Override
	public void mainAct(Army army, Scenario scenario) {
		Coordinate targetCoor = this.getTarget();
		BattleMap map = scenario.getBattleMap();
		Group[] group = scenario.getGroup();
		Building build = map.getBuilding(targetCoor.getLocationX(),
				targetCoor.getLocationY());
		if (build != null) {
			int id = build.getGroupID();
			int allyID = army.getGroupID();
			if (id != DEFAULT_MAX_GROUP) {
				if (group[id].getSide() != group[allyID].getSide()) {
					if (group[allyID].getNumberBuilding() < DEFAULT_MAX_BUILDING_PER_GROUP) {
						switch (build.getBuildingType()) {
						case UNKNOWN_TYPE: {
							scenario.addNewBuilding(build.getName(), allyID,
									build.getDefense(),
									build.getObstaclePoint(),
									build.getBuildingType(),
									build.getLocationX(), build.getLocationY(),
									build.getDataID());
							group[id].removeBuilding(build.getID());
							army.setExperience(army.getExperience() + 1000,
									armyManager);
							break;
						}
						case PRODUCE_GOLD_TYPE: {
							scenario.addGoldBuilding(build.getName(), allyID,
									build.getDefense(),
									build.getObstaclePoint(),
									build.getBuildingType(),
									((Gold_Building) build).getGoldProduce(),
									build.getLocationX(), build.getLocationY(),
									build.getDataID());
							group[id].removeBuilding(build.getID());
							army.setExperience(army.getExperience() + 2000,
									armyManager);
							break;
						}
						case RESTORE_HP_TYPE: {
							scenario.addHPBuilding(build.getName(), allyID,
									build.getDefense(),
									build.getObstaclePoint(),
									build.getBuildingType(),
									((HP_Building) build).getGoldProduce(),
									((HP_Building) build).getHPRestore(),
									build.getLocationX(), build.getLocationY(),
									build.getDataID());
							group[id].removeBuilding(build.getID());
							army.setExperience(army.getExperience() + 2500,
									armyManager);
							break;
						}
						case PRODUCE_ARMY_TYPE: {
							scenario.addArmyBuilding(build.getName(), allyID,
									build.getDefense(), build
											.getObstaclePoint(), build
											.getBuildingType(),
									((Army_Building) build).getGoldProduce(),
									((Army_Building) build).getHPRestore(),
									((Army_Building) build)
											.getArmyProduceType(), build
											.getLocationX(), build
											.getLocationY(), build.getDataID());
							group[id].removeBuilding(build.getID());
							army.setExperience(army.getExperience() + 3500,
									armyManager);
							break;
						}
						case HEAD_QUARTER_TYPE:
							if (((HQ_Building) build).getTurnsBeforeLost() == MANY_TURNS) {
								((HQ_Building) build).occupy();
							} else if (((HQ_Building) build)
									.getTurnsBeforeLost() == 0) {
								scenario.removeHQBuilding(id,
										build.getLocationX(),
										build.getLocationY());
								group[id].setLost(true);
							}
							army.setExperience(army.getExperience() + 5000,
									armyManager);
							break;
						}
					}
				} else if (((HQ_Building) build).getTurnsBeforeLost() != MANY_TURNS) {
					((HQ_Building) build).setTurnsBeforeLost(MANY_TURNS);
					army.setExperience(army.getExperience() + 5000, armyManager);
				}
			} else {
				switch (build.getBuildingType()) {
				case UNKNOWN_TYPE: {
					scenario.addNewBuilding(build.getName(), allyID,
							build.getDefense(), build.getObstaclePoint(),
							build.getBuildingType(), build.getLocationX(),
							build.getLocationY(), build.getDataID());
					scenario.removeNeutralBuilding(build);
					army.setExperience(army.getExperience() + 1000, armyManager);
					break;
				}
				case PRODUCE_GOLD_TYPE: {
					scenario.addGoldBuilding(build.getName(), allyID,
							build.getDefense(), build.getObstaclePoint(),
							build.getBuildingType(),
							((Gold_Building) build).getGoldProduce(),
							build.getLocationX(), build.getLocationY(),
							build.getDataID());
					scenario.removeNeutralBuilding(build);
					army.setExperience(army.getExperience() + 2000, armyManager);
					break;
				}
				case RESTORE_HP_TYPE: {
					scenario.addHPBuilding(build.getName(), allyID,
							build.getDefense(), build.getObstaclePoint(),
							build.getBuildingType(),
							((HP_Building) build).getGoldProduce(),
							((HP_Building) build).getHPRestore(),
							build.getLocationX(), build.getLocationY(),
							build.getDataID());
					scenario.removeNeutralBuilding(build);
					army.setExperience(army.getExperience() + 2500, armyManager);
					break;
				}
				case PRODUCE_ARMY_TYPE: {
					scenario.addArmyBuilding(build.getName(), allyID,
							build.getDefense(), build.getObstaclePoint(),
							build.getBuildingType(),
							((Army_Building) build).getGoldProduce(),
							((Army_Building) build).getHPRestore(),
							((Army_Building) build).getArmyProduceType(),
							build.getLocationX(), build.getLocationY(),
							build.getDataID());
					scenario.removeNeutralBuilding(build);
					army.setExperience(army.getExperience() + 3500, armyManager);
					break;
				}
				}
			}
		}
	}

	@Override
	public void calculation(Army army, Scenario scenario) {
		Coordinate targetCoor = this.getTarget();
		BattleMap map = scenario.getBattleMap();
		Group[] group = scenario.getGroup();
		Building build = map.getBuilding(targetCoor.getLocationX(),
				targetCoor.getLocationY());
		if (build != null) {
			int id = build.getGroupID();
			int allyID = army.getGroupID();
			if (id != DEFAULT_MAX_GROUP) {
				if (group[id].getSide() != group[allyID].getSide()) {
					if (group[allyID].getNumberBuilding() < DEFAULT_MAX_BUILDING_PER_GROUP) {
						switch (build.getBuildingType()) {
						case UNKNOWN_TYPE:
							this.setAbilityPoint(3500);
							break;
						case PRODUCE_GOLD_TYPE:
							this.setAbilityPoint(5000);
							break;
						case RESTORE_HP_TYPE:
							this.setAbilityPoint(6500);
							break;
						case PRODUCE_ARMY_TYPE:
							this.setAbilityPoint(8000);
							break;
						case HEAD_QUARTER_TYPE:
							this.setAbilityPoint(10000);
							break;
						}
					}
				} else if (build.getBuildingType() == HEAD_QUARTER_TYPE) {
					if (((HQ_Building) build).getTurnsBeforeLost() != MANY_TURNS) {
						this.setAbilityPoint(20000);
					} else {
						this.setAbilityPoint(2000);
					}
				}
			} else {
				switch (build.getBuildingType()) {
				case UNKNOWN_TYPE:
					this.setAbilityPoint(3000);
					break;
				case PRODUCE_GOLD_TYPE:
					this.setAbilityPoint(4000);
					break;
				case RESTORE_HP_TYPE:
					this.setAbilityPoint(5000);
					break;
				case PRODUCE_ARMY_TYPE:
					this.setAbilityPoint(6000);
					break;
				}
			}
		}
	}

	@Override
	public ArrayList<Coordinate> calculateAffectedArea(Army army,
			Scenario scenario) {
		ArrayList<Coordinate> area = new ArrayList<Coordinate>(1);
		area.add(army.getCoordinate());
		return area;
	}
}
